package token

import (
	"encoding/json"
	"time"

	"gitee.com/shiwjlinux/vblog01/apps/user"
	"github.com/rs/xid"
)

func NewToken(u *user.User) *Token {
	return &Token{
		UserId:                u.Id,
		Username:              u.Username,
		AccessToken:           xid.New().String(),
		AccessTokenExpiredAt:  3600,
		RefreshToken:          xid.New().String(),
		RefreshTokenExpiredAt: 3600 * 4,
		Role:                  u.Role,
	}
}

func DefaultToken() *Token {
	return &Token{}
}

type Token struct {
	UserId                int       `json:"user_id"`
	Username              string    `json:"username"`
	AccessToken           string    `json:"access_token"`
	AccessTokenExpiredAt  int       `json:"access_token_expired_at"`
	RefreshToken          string    `json:"refresh_token"`
	RefreshTokenExpiredAt int       `json:"refresh_token_expired_at"`
	CreatedAt             int64     `json:"created_at"`
	UpdatedAt             int64     `json:"updated_at"`
	Role                  user.Role `json:"role" gorm:"-"`
}

func (t *Token) TableName() string {
	return AppName + "s"
}

func (t *Token) String() string {
	b, _ := json.MarshalIndent(t, "", "  ")
	return string(b)
}

func (t *Token) IssueTime() time.Time {
	return time.Unix(t.CreatedAt, 0)
}

func (t *Token) RefreshTokenDuration() time.Duration {
	return time.Duration(t.RefreshTokenExpiredAt * int(time.Second))
}

func (t *Token) AccessTokenDuration() time.Duration {
	return time.Duration(t.AccessTokenExpiredAt * int(time.Second))
}

func (t *Token) RefreshTokenIsExpired() error {
	expiredTime := t.IssueTime().Add(t.RefreshTokenDuration())
	if time.Since(expiredTime).Seconds() > 0 {
		return ErrorRefreshTokenExpired
	}
	return nil
}

func (t *Token) AccessTokenIsExpired() error {
	expiredTime := t.IssueTime().Add(t.AccessTokenDuration())
	if time.Since(expiredTime).Seconds() > 0 {
		return ErrorAccessTokenExpired
	}
	return nil
}
